package com.demo.base.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Random;

import org.apache.log4j.Logger;


/**
 * 日期时间工具类
 *
 */
public class DateTimeUtil {

	private static final Logger logger = Logger.getLogger(DateTimeUtil.class);

	private final static String dayNames[] = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };

	/**
	 * yyyy-MM-dd
	 */
	public static int yyyy_MM_dd = 0;
	/**
	 * yyyy-MM-dd HH:mm:ss
	 */
	public static int yyyy_MM_dd_HH_mm_ss = 1;
	/**
	 * HH:mm:ss
	 */
	public static int HH_mm_ss = 2;
	/**
	 * yyyyMMddHHmmss
	 */
	public static int yyyyMMddHHmmss = 3;
	/**
	 * yyyyMMddHHmmssSS
	 */
	public static int yyyyMMddHHmmssSSS = 4;
	/**
	 * yyyy年MM月dd日
	 */
	public static int c_yyyy_MM_dd_ = 5;
	/**
	 * yyyy年MM月dd日HH时mm分ss秒
	 */
	public static int c_yyyy_MM_dd_HH_mm_ss_ = 6;
	/**
	 * yyyy
	 */
	public static int yyyy = 7;
	/**
	 * MM
	 */
	public static int MM = 8;
	/**
	 * dd
	 */
	public static int dd = 9;
	/**
	 * yyyyMMdd
	 */
	public static int yyyyMMdd = 10;
	/**
	 * yyyy-MM
	 */
	public static int yyyy_MM = 11;
	/**
	 * yyyy年MM月dd日 EE
	 */
	public static int c_yyyy_MM_dd_EE = 12;
	/**
	 * yyyy/MM/dd HH:mm:ss
	 */
	public static int x_yyyy_MM_dd_HH_mm_ss = 13;

	/**
	 * HHmmss
	 */
	public static int HHmmss = 14;

	/**
	 * HHmmssSS
	 */
	public static int HHmmssSSS = 15;

	/**
	 * yyyyMM
	 */
	public static int yyyyMM = 17;

	/**
	 * 格式化日期样式
	 * @param caseNum
	 * @return
	 */
	public static SimpleDateFormat getDateFormat(int caseNum) {
		SimpleDateFormat dateFormat = null;
		switch (caseNum) {
		case 0:
			dateFormat = new SimpleDateFormat("yyyy-MM-dd");
			break;
		case 1:
			dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			break;
		case 2:
			dateFormat = new SimpleDateFormat("HH:mm:ss");
			break;
		case 3:
			dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
			break;
		case 4:
			dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
			break;
		case 10:
			dateFormat = new SimpleDateFormat("yyyyMMdd");
			break;
		case 5:
			dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
			break;
		case 6:
			dateFormat = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
			break;
		case 7:
			dateFormat = new SimpleDateFormat("yyyy");
			break;
		case 8:
			dateFormat = new SimpleDateFormat("MM");
			break;
		case 9:
			dateFormat = new SimpleDateFormat("dd");
			break;
		case 11:
			dateFormat = new SimpleDateFormat("yyyy-MM");
			break;
		case 12:
			dateFormat = new SimpleDateFormat("yyyy年MM月dd日 EE");
			break;
		case 13:
			dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
			break;
		case 14:
			dateFormat = new SimpleDateFormat("HHmmss");
			break;
		case 15:
			dateFormat = new SimpleDateFormat("HHmmssSSS");
			break;
		case 16:
			dateFormat = new SimpleDateFormat("yyyy/MM/dd");
			break;
		case 17:
			dateFormat = new SimpleDateFormat("yyyyMM");
			break;
		default:
			break;
		}
		return dateFormat;
	}

	/**
	 * 把日期转换为字符串
	 * @param date
	 * @param caseNum
	 * @return
	 */
	public static String formatDate(Date date, int caseNum) {
		String dateStr = null;
		SimpleDateFormat dateFormat = getDateFormat(caseNum);
		dateStr = dateFormat.format(date);
		return dateStr;
	}

	/**
	 * 把字符串转换为日期
	 * @param dateStr
	 * @param caseNum
	 * @return
	 */
	public static Date parseDate(String dateStr, int caseNum) {
		Date date = null;
		try {
			SimpleDateFormat dateFormat = getDateFormat(caseNum);
			date = dateFormat.parse(dateStr);
		} catch (Exception e) {
			logger.error("parseDate error:", e);
		}
		return date;
	}

	/**
	 * 获取当前时间的字符串形式
	 * @param caseNum
	 * @return
	 * @throws Exception
	 */
	public static String getNowDateStr(int caseNum) {
		Date date = new Date();
		SimpleDateFormat dateFormat = getDateFormat(caseNum);
		String dateStr = dateFormat.format(date);
		return dateStr;
	}

	/**
	 * 得到年份
	 * @param c
	 * @return
	 */
	public static int getYear(Calendar c) {
		return c.get(Calendar.YEAR);
	}

	/**
	 * 得到当前年份
	 * @return
	 */
	public static int getYear() {
		return Calendar.getInstance().get(Calendar.YEAR);
	}

	/**
	 * 得到月份
	 * @param c
	 * @return
	 */
	public static int getMonth(Calendar c) {
		return c.get(Calendar.MONTH);
	}

	/**
	 * 得到当前月份
	 * @return
	 */
	public static int getMonth() {
		return Calendar.getInstance().get(Calendar.MONTH);
	}

	/**
	 * 得到日
	 * @param c
	 * @return
	 */
	public static int getDate(Calendar c) {
		return c.get(Calendar.DATE);
	}

	/**
	 * 得到当前日
	 * @return
	 */
	public static int getDate() {
		return Calendar.getInstance().get(Calendar.DATE);
	}

	/**
	 * 得到星期
	 * @param c
	 * @return
	 */
	public static int getDay(Calendar c) {
		return c.get(Calendar.DAY_OF_WEEK);
	}

	/**
	 * 得到当前星期
	 * @return
	 */
	public static int getDay() {
		return Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
	}

	/**
	 * 得到星期
	 * @param c
	 * @return
	 */
	public static String getChineseDay(Calendar c) {
		return dayNames[getDay(c) - 1];
	}

	/**
	 * 得到当前星期（中文）
	 * @return
	 */
	public static String getChineseDay() {
		return dayNames[getDay() - 1];
	}

	/**
	 * 得到小时
	 * @param c
	 * @return
	 */
	public static int getHour(Calendar c) {
		return c.get(Calendar.HOUR);
	}

	/**
	 * 得到当前小时
	 * @return
	 */
	public static int getHour() {
		return Calendar.getInstance().get(Calendar.HOUR);
	}

	/**
	 * 昨天
	 * @param c
	 * @return
	 */
	public static Calendar yesterday(Calendar c) {
		long offset = 1 * 24 * 60 * 60 * 1000;
		c.setTimeInMillis(c.getTimeInMillis() - offset);
		return c;
	}

	/**
	 * 当前时间的昨天
	 * @return
	 */
	public static Calendar yesterday() {
		long offset = 1 * 24 * 60 * 60 * 1000;
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(c.getTimeInMillis() - offset);
		return c;
	}

	/**
	 * 明天
	 * @param c
	 * @return
	 */
	public static Calendar tomorrow(Calendar c) {
		long offset = 1 * 24 * 60 * 60 * 1000;
		c.setTimeInMillis(c.getTimeInMillis() + offset);
		return c;
	}

	/**
	 * 当前时间的明天
	 * @return
	 */
	public static Calendar tomorrow() {
		long offset = 1 * 24 * 60 * 60 * 1000;
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(c.getTimeInMillis() + offset);
		return c;
	}

	/**
	 * Date类型转换到Calendar类型
	 * @param d
	 * @return
	 */
	public static Calendar Date2Calendar(Date d) {
		Calendar c = Calendar.getInstance();
		c.setTime(d);
		return c;
	}

	/**
	 * Calendar类型转换到Date类型
	 * @param c
	 * @return
	 */
	public static Date Calendar2Date(Calendar c) {
		return c.getTime();
	}

	/**
	 * 计算两个日期之间相差的天数
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static int daysBetweenDate(Date startDate, Date endDate) {
		Long interval = endDate.getTime() - startDate.getTime();
		interval = interval / (24 * 60 * 60 * 1000);
		return interval.intValue();
	}

	/**
	 * 日期加减
	 * @param date 起始日期
	 * @param formatCaseNum 日期格式
	 * @param calendarType 日期计算方式Calender常量(YEAR：加年,MONTH：加月,DATE：加天,HOUR：加小时,MINUTE:分钟,SECOND：加秒)
	 * @param num 需要加减的数量
	 * @return
	 * @throws Exception
	 */
	static public String addDate(String date, int formatCaseNum, int calendarType, int num) {
		SimpleDateFormat format = null;
		Calendar calendar = Calendar.getInstance();
		try {
			format = getDateFormat(formatCaseNum);
			calendar.setTime(format.parse(date));
			calendar.add(calendarType, num);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return format.format(calendar.getTime());
	}

	/**
	 * 判断是否是周末
	 * @param date
	 * @return
	 */
	public static boolean isWeekend(String d) {
		return isWeekend(parseDate(d, yyyy_MM_dd));
	}

	public static boolean isWeekend(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int day = c.get(Calendar.DAY_OF_WEEK);
		if (day == 1 || day == 7) {
			return true;
		}
		return false;
	}

	/**
	 * 查询指定季度的第一个月和最后一个月
	 * @param year 年度
	 * @param quarter  季度
	 * @param type  0表示季度的第一个月  1表示季度的最后一个月
	 * @return
	 */
	public static String getQuarterMonth(String year, String quarter, int type) {
		String rs = "";
		if (type == 0) {
			switch (Integer.parseInt(quarter)) {
			case 1:
				rs = year + "-01";
				break;
			case 2:
				rs = year + "-04";
				break;
			case 3:
				rs = year + "-07";
				break;
			case 4:
				rs = year + "-10";
				break;
			default:
				break;
			}
		} else {
			switch (Integer.parseInt(quarter)) {
			case 1:
				rs = year + "-03";
				break;
			case 2:
				rs = year + "-06";
				break;
			case 3:
				rs = year + "-09";
				break;
			case 4:
				rs = year + "-12";
				break;
			default:
				break;
			}
		}
		return rs;
	}

	/**
	 * 给定日期是第几季度
	 * @param date
	 * @return
	 */
	public static int getQuarter(Date date) {
		int quarter = 0;
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int month = getMonth(c);
		if (month >= 0 && month <= 2) {
			quarter = 1;
		} else if (month >= 3 && month <= 5) {
			quarter = 2;
		} else if (month >= 6 && month <= 8) {
			quarter = 3;
		} else if (month >= 9 && month <= 11) {
			quarter = 4;
		}
		return quarter;
	}

	/**
	 * 判断某个日期是否在某个日期范围 
	 * @param beginDate
	 * @param endDate
	 * @param src
	 * @return
	 */
	public static boolean isBetween(Date beginDate, Date endDate, Date src) {
		return beginDate.before(src) && endDate.after(src);
	}

	/**
	 * 比较2个日期
	 * @param beginDate
	 * @param endDate
	 * @param format
	 * @return
	 * @throws ParseException
	 */
	public static int compareDate(String dt1, String dt2, int format) {
		int num = 0;
		Date date1;
		Date date2;
		date1 = parseDate(dt1, format);
		date2 = parseDate(dt2, format);
		if (date1.after(date2)) {
			num = 1;
		} else if (date1.before(date2)) {
			num = -1;
		}
		return num;
	}

	/**
	 * 获得两个时间段内的所有日期
	 * 
	 * @param d1
	 * @param d2
	 * @return
	 * @throws ParseException
	 * @throws java.text.ParseException
	 */
	public static List<String> getBetweenDate(String d1, String d2) throws ParseException, java.text.ParseException {
		List<String> v = new ArrayList<String>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		GregorianCalendar gc1 = new GregorianCalendar(), gc2 = new GregorianCalendar();
		gc1.setTime(sdf.parse(d1));
		gc2.setTime(sdf.parse(d2));
		if (gc1.after(gc2)) {
			GregorianCalendar swap = gc1;
			gc1 = gc2;
			gc2 = swap;
		}
		do {
			GregorianCalendar gc3 = (GregorianCalendar) gc1.clone();
			v.add(sdf.format(gc3.getTime()));
			gc1.add(Calendar.DAY_OF_MONTH, 1);
		} while (!gc1.after(gc2));
		return v;
	}

	/** 
	 * @param 要转换的毫秒数 
	 * @return 该毫秒数转换为 * days * hours * minutes * seconds 后的格式 
	 * @author fy.zhang 
	 */
	public static String formatDuring(long mss) {
		long days = mss / (60 * 60 * 24);
		long hours = (mss % (60 * 60 * 24)) / (60 * 60);
		long minutes = (mss % (60 * 60)) / (60);
		long seconds = (mss % (60));

		String str = "";
		if (days > 0) {
			str += days + " 天 ";
		}
		if (hours > 0) {
			str += hours + " 小时 ";
		}
		if (minutes > 0) {
			str += minutes + " 分钟 ";
		}
		if (seconds > 0) {
			str += seconds + " 秒 ";
		}
		/*
		 * return days + " 天 " + hours + " 小时 " + minutes + " 分钟 " + seconds +
		 * " 秒 ";
		 */
		return str;
	}

	/**
	 * 获取某月分第一天,如果没有指定date 则默认本月第一天
	 * @param date
	 * @return
	 */
	public static String firstDayForMonth(Date date) {
		// 获取Calendar
		Calendar calendar = Calendar.getInstance();
		if (date != null) {
			calendar.setTime(date);
		}
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		String dateStr = dateFormat.format(calendar.getTime());
		return dateStr;
	}

	/**
	 * 获取某月分最后一天,如果没有指定date 则默认本月最后一天
	 * @param date
	 * @return  yyyy-mm-dd
	 */
	public static String lastDayForMonth(Date date) {
		// 获取Calendar
		Calendar calendar = Calendar.getInstance();
		if (date != null) {
			calendar.setTime(date);
		}
		calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		String dateStr = dateFormat.format(calendar.getTime());
		return dateStr;
	}

	/**
	 * 获取随机小时，排除中午12点 及早上9点以前
	 * 
	 * @param hh
	 * @return
	 */
	public static String getHour(String hh) {
		String rs = addZeroInt(getRandomInt(Integer.parseInt(hh) + 1));
		if (rs.equals("12") || Integer.parseInt(rs) < 9) {
			rs = getHour(hh);
		}
		return rs;
	}

	/**
	 * 数字小于10 则 前面加0 返回字符串
	 * 
	 * @param m
	 * @return
	 */
	public static String addZeroInt(int m) {
		String rs = "";
		if (m < 10) {
			rs = "0" + m;
		} else {
			rs = String.valueOf(m);
		}
		return rs;
	}

	/**
	 * 指定范围的随机数
	 * 
	 * @param m
	 * @return
	 */
	public static int getRandomInt(int m) {
		Random random = new Random();
		int k = Math.abs(random.nextInt()) % m;
		return k;
	}

	/**
	 * 随机获取更小的时间
	 * 
	 * @param time
	 * @return
	 */
	public static String getRandomDateTime(String time) {
		String yyyy = time.substring(0, 10);
		String hh = time.substring(11, 13);
		String mm = time.substring(14, 16);
		String ss = time.substring(17, 19);

		String newhh = "";
		if (Integer.parseInt(hh) < 9) {
			newhh = hh;
		} else {
			newhh = getHour(hh);
		}

		String newmm = "";
		if (newhh.equals(hh)) {
			newmm = addZeroInt(getRandomInt(Integer.parseInt(mm) + 1));
		} else {
			newmm = addZeroInt(getRandomInt(60));
		}
		String newss = "";
		if (newhh.equals(hh)) {
			newss = addZeroInt(getRandomInt(Integer.parseInt(ss) + 1));
		} else {
			newss = addZeroInt(getRandomInt(60));
		}
		String newtime = yyyy + " " + newhh + ":" + newmm + ":" + newss;
		return newtime;
	}
	
	
}
